package com.ssy.lingxi.member.merchant.serviceimpl.feign;

import cn.hutool.core.collection.CollectionUtil;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Projections;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import com.ssy.lingxi.common.constant.member.MemberLevelTypeEnum;
import com.ssy.lingxi.common.constant.member.MemberStatusEnum;
import com.ssy.lingxi.common.constant.member.MemberTypeEnum;
import com.ssy.lingxi.common.constant.member.RoleTypeEnum;
import com.ssy.lingxi.common.model.dto.MemberAndRoleIdDTO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.common.utils.CollectionPageUtil;
import com.ssy.lingxi.common.utils.DateTimeUtil;
import com.ssy.lingxi.common.utils.PasswordUtil;
import com.ssy.lingxi.member.merchant.api.constant.MemberPayPasswordCheckEnum;
import com.ssy.lingxi.member.merchant.api.constant.MemberRelationTypeEnum;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.request.*;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.*;
import com.ssy.lingxi.member.merchant.config.ServiceConfig;
import com.ssy.lingxi.member.merchant.entity.*;
import com.ssy.lingxi.member.merchant.model.constant.MemberOuterStatusEnum;
import com.ssy.lingxi.member.merchant.model.constant.MemberValidateStatusEnum;
import com.ssy.lingxi.member.merchant.model.vo.basic.response.MemberRegisterTagVO;
import com.ssy.lingxi.member.merchant.repository.*;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberRegisterDetailService;
import com.ssy.lingxi.member.merchant.service.base.IBaseMemberShopService;
import com.ssy.lingxi.member.merchant.service.feign.IMemberFeignService;
import com.ssy.lingxi.member.merchant.utils.NumberUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 会员信息查询对外Feign接口实现类
 * @author 万宁
 * @version 2.0.0
 * @date 2020-08-11
 */
@Service
public class MemberFeignServiceImpl implements IMemberFeignService {
    @Resource
    private IBaseMemberShopService baseMemberShopService;

    @Resource
    private MemberRepository memberRepository;

    @Resource
    private RoleRepository roleRepository;

    @Resource
    private RoleTypeRepository roleTypeRepository;

    @Resource
    private MemberRelationRepository relationRepository;

    @Resource
    private IBaseMemberRegisterDetailService baseMemberRegisterDetailService;

    @Resource
    private MemberUserRepository memberUserRepository;

    @Resource
    private JPAQueryFactory jpaQueryFactory;

    /**
     * 新增会员支付策略 - 查询作为服务提供者的会员信息列表
     *
     * @param pageVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<PageData<MemberFeignPayProviderResultVO>> findPayProviderMembers(MemberFeignPayProviderVO pageVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), MemberStatusEnum.NORMAL.getCode()));

            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));

            Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
            if (StringUtils.hasLength(pageVO.getMemberName())) {
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + pageVO.getMemberName().trim() + "%"));
            }

            if (!CollectionUtils.isEmpty(pageVO.getItems())) {
                List<Predicate> orList = new ArrayList<>();
                for (MemberFeignPayProviderVO.MemberItem item : pageVO.getItems()) {
                    orList.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), item.getMemberId()), criteriaBuilder.equal(root.get("subRoleId").as(Long.class), item.getRoleId())));
                }
                Predicate[] orP = new Predicate[orList.size()];
                list.add(criteriaBuilder.or(orList.toArray(orP)));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        Pageable page = PageRequest.of(pageVO.getCurrent() - 1, pageVO.getPageSize(), Sort.by("id").descending());
        Page<MemberRelationDO> pageList = relationRepository.findAll(specification, page);

        return Wrapper.success(new PageData<>(pageList.getTotalElements(), pageList.getContent().stream().map(relationDO -> {
            MemberFeignPayProviderResultVO resultVO = new MemberFeignPayProviderResultVO();
            resultVO.setId(relationDO.getId());
            resultVO.setMemberId(relationDO.getSubMemberId());
            resultVO.setMemberName(relationDO.getSubMember().getName());
            resultVO.setRoleId(relationDO.getSubRoleId());
            resultVO.setRoleName(relationDO.getSubRoleName());
            resultVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            resultVO.setLevel(relationDO.getLevelRight() == null ? 0 :relationDO.getLevelRight().getLevel());
            resultVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
            return resultVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 新增会员支付策略 - 选择适用会员
     *
     * @param pageVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<PageData<MemberFeignPayProviderResultVO>> pageNewPayProviderMembers(MemberFeignPayProviderExcludeVO pageVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), MemberStatusEnum.NORMAL.getCode()));

            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));

            if (StringUtils.hasLength(pageVO.getMemberName())) {
                Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + pageVO.getMemberName().trim() + "%"));
            }

            if (pageVO.getRoleId() != null && !pageVO.getRoleId().equals(0L)) {
                list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), pageVO.getRoleId()));
            }

            if (pageVO.getMemberTypeId() != null && !pageVO.getMemberTypeId().equals(0L)) {
                list.add(criteriaBuilder.equal(subRoleJoin.get("memberType").get("id").as(Long.class), pageVO.getMemberTypeId()));
            }

            if (pageVO.getLevel() != null && !pageVO.getLevel().equals(0)) {
                Join<Object, Object> levelRightJoin = root.join("levelRight", JoinType.LEFT);
                list.add(criteriaBuilder.equal(levelRightJoin.get("level").as(Integer.class), pageVO.getLevel()));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };


        List<MemberRelationDO> relationDOList = relationRepository.findAll(specification, Sort.by("id").ascending());

        if (!CollectionUtils.isEmpty(pageVO.getExcludeList())) {
            relationDOList = relationDOList.stream().filter(relationDO -> pageVO.getExcludeList().stream().noneMatch(exist -> exist.getMemberId().equals(relationDO.getSubMemberId()) && exist.getRoleId().equals(relationDO.getSubRoleId()))).collect(Collectors.toList());
        }

        int totalCount = relationDOList.size();

        List<MemberRelationDO> pageList = CollectionPageUtil.pageList(relationDOList, totalCount, pageVO.getCurrent(), pageVO.getPageSize());

        return Wrapper.success(new PageData<>((long) totalCount, pageList.stream().map(relationDO -> {
            MemberFeignPayProviderResultVO resultVO = new MemberFeignPayProviderResultVO();
            resultVO.setId(relationDO.getId());
            resultVO.setMemberId(relationDO.getSubMemberId());
            resultVO.setMemberName(relationDO.getSubMember().getName());
            resultVO.setRoleId(relationDO.getSubRoleId());
            resultVO.setRoleName(relationDO.getSubRoleName());
            resultVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            resultVO.setLevel(relationDO.getLevelRight().getLevel());
            resultVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            return resultVO;
        }).collect(Collectors.toList())));
    }

    /**
     * 模板服务 - 模糊查询会员信息列表
     *
     * @param listVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberFeignListResultVO>> findMembersFromTemplateService(MemberFeignListVO listVO) {
        String name = StringUtils.hasLength(listVO.getName()) ? listVO.getName().trim() : "";

        List<MemberDO> memberDOList = memberRepository.findByNameContainsAndIdIn(name, listVO.getMemberIds());

        return Wrapper.success(memberDOList.stream().filter(memberDO -> !memberDO.getAccount().equals(ServiceConfig.PLATFORM_SUPER_ADMIN_ACCOUNT)).map(memberDO -> {
            MemberFeignListResultVO resultVO = new MemberFeignListResultVO();
            resultVO.setMemberId(memberDO.getId());
            resultVO.setName(StringUtils.hasLength(memberDO.getName()) ? memberDO.getName() : "");
            return resultVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id和角色Id，查询上属会员列表（不区分企业会员、渠道会员）
     * <p>其中等级为当前会员在其上级会员和上级会员角色下的等级</p>
     *
     * @param feignVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberFeignQueryVO>> listUpperMembers(MemberFeignVO feignVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), feignVO.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), feignVO.getRoleId()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            Join<Object, Object> subRoleJoin = root.join("role", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification).stream().map(relationDO -> {
            MemberFeignQueryVO queryVO = new MemberFeignQueryVO();
            queryVO.setMemberId(relationDO.getMemberId());
            queryVO.setMemberName(relationDO.getMember().getName());
            queryVO.setLogo(StringUtils.hasLength(relationDO.getMember().getLogo()) ? relationDO.getMember().getLogo() : "");
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setRoleId(relationDO.getRoleId());
            queryVO.setRoleName(relationDO.getSubRoleName());
            queryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());

            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id和角色Id，查询上级“渠道会员”列表
     *
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignRoleIdAndNameVO>> listUpperChannelMembers(MemberFeignVO feignVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), feignVO.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), feignVO.getRoleId()));
            Join<Object, Object> roleJoin = root.join("role", JoinType.LEFT);
            list.add(criteriaBuilder.or(criteriaBuilder.equal(roleJoin.get("memberType").get("typeEnum").as(Integer.class), MemberTypeEnum.CHANNEL.getCode()), criteriaBuilder.equal(roleJoin.get("memberType").get("typeEnum").as(Integer.class), MemberTypeEnum.CHANNEL_PERSONAL.getCode())));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification, Sort.by("id").ascending()).stream().map(relationDO -> {
            MemberFeignRoleIdAndNameVO queryVO = new MemberFeignRoleIdAndNameVO();
            queryVO.setMemberId(relationDO.getMemberId());
            queryVO.setName(relationDO.getMember().getName());
            queryVO.setRoleId(relationDO.getRoleId());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id和角色Id，查询下属会员列表（不区分企业会员、渠道会员）
     * <p>其中等级为下级会员和角色在当前会员和角色下的等级</p>
     *
     * @param feignVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberFeignQueryVO>> listLowerMembers(MemberFeignSubVO feignVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), feignVO.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), feignVO.getRoleId()));
            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_CONSUMER.getCode()));

            if (feignVO.getMemberTypeId() != null && !feignVO.getMemberTypeId().equals(0L)) {
                list.add(criteriaBuilder.equal(subRoleJoin.get("memberType").get("id").as(Long.class), feignVO.getMemberTypeId()));
            }

            if (feignVO.getSubRoleId() != null && !feignVO.getSubRoleId().equals(0L)) {
                list.add(criteriaBuilder.equal(root.get("subRoleId").as(Long.class), feignVO.getSubRoleId()));
            }

            if (feignVO.getLevel() != null && !feignVO.getLevel().equals(0)) {
                Join<Object, Object> levelJoin = root.join("levelRight", JoinType.LEFT);
                list.add(criteriaBuilder.equal(levelJoin.get("level").as(Integer.class), feignVO.getLevel()));
            }

            if (StringUtils.hasLength(feignVO.getSubMemberName())) {
                Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
                list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), feignVO.getSubMemberName().trim()));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification).stream().map(relationDO -> {
            MemberFeignQueryVO queryVO = new MemberFeignQueryVO();
            queryVO.setMemberId(relationDO.getSubMemberId());
            queryVO.setLogo(StringUtils.hasLength(relationDO.getSubMember().getLogo()) ? relationDO.getSubMember().getLogo() : "");
            queryVO.setMemberName(relationDO.getSubMember().getName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setRoleId(relationDO.getSubRoleId());
            queryVO.setRoleName(relationDO.getSubRoleName());
            queryVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id和角色Id，查询“审核通过”的下属会员列表（不区分渠道类型、角色类型）
     * <p>其中等级为下级会员和角色在当前会员和角色下的等级</p>
     *
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignQueryVO>> listAllLowerMembers(MemberFeignVO feignVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), feignVO.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), feignVO.getRoleId()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification).stream().map(relationDO -> {
            MemberFeignQueryVO queryVO = new MemberFeignQueryVO();
            queryVO.setMemberId(relationDO.getSubMemberId());
            queryVO.setLogo(StringUtils.hasLength(relationDO.getSubMember().getLogo()) ? relationDO.getSubMember().getLogo() : "");
            queryVO.setMemberName(relationDO.getSubMember().getName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setRoleId(relationDO.getSubRoleId());
            queryVO.setRoleName(relationDO.getSubRoleName());
            queryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            queryVO.setLevel(relationDO.getLevelRight().getLevel());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id和角色Id，查询“审核通过”的下级会员列表（角色类型为服务提供者）
     * <p>返回结果中的等级为下级会员和角色在当前会员和角色下的等级</p>
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignQueryVO>> listSubProviderLowerMembers(MemberFeignVO feignVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), feignVO.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("roleId").as(Long.class), feignVO.getRoleId()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification).stream().map(relationDO -> {
            MemberFeignQueryVO queryVO = new MemberFeignQueryVO();
            queryVO.setMemberId(relationDO.getSubMemberId());
            queryVO.setLogo(StringUtils.hasLength(relationDO.getSubMember().getLogo()) ? relationDO.getSubMember().getLogo() : "");
            queryVO.setMemberName(relationDO.getSubMember().getName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setRoleId(relationDO.getSubRoleId());
            queryVO.setRoleName(relationDO.getSubRoleName());
            queryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            queryVO.setLevel(relationDO.getLevelRight().getLevel());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id、角色Id、上级会员Id、上级会员角色Id，查询会员信息
     * <p>其中等级为当前会员在其上级会员和上级会员角色下的等级</p>
     *
     * @param feignVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberFeignQueryVO> getMemberInfo(MemberRelationFeignVO feignVO) {
        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(feignVO.getUpperMemberId(), feignVO.getUpperRoleId(), feignVO.getMemberId(), feignVO.getRoleId());
        if (relationDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        MemberFeignQueryVO queryVO = new MemberFeignQueryVO();
        queryVO.setSubMemberName(relationDO.getSubMember().getName());
        queryVO.setLogo(StringUtils.hasLength(relationDO.getMember().getLogo()) ? relationDO.getMember().getLogo() : "");
        queryVO.setMemberId(relationDO.getSubMemberId());
        queryVO.setMemberName(relationDO.getMember().getName());
        queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
        queryVO.setRoleId(relationDO.getSubRoleId());
        queryVO.setRoleName(relationDO.getSubRoleName());
        queryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());

        return Wrapper.success(queryVO);
    }

    /**
     * 根据会员Id，查询会员注册信息
     *
     * @param idVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<MemberFeignRegisterQueryVO> getMemberRegisterInfo(MemberFeignIdVO idVO) {
        Wrapper<MemberRegisterTagVO> result = baseMemberRegisterDetailService.getMemberRegisterTagDetail(idVO.getMemberId());
        if (result.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(result.getCode(), result.getMessage());
        }

        MemberFeignRegisterQueryVO queryVO = new MemberFeignRegisterQueryVO();
        if (result.getData() != null) {
            queryVO.setMemberId(result.getData().getMemberId());
            queryVO.setName(result.getData().getName());
            queryVO.setPhone(result.getData().getPhone());
            queryVO.setIdentityCard(result.getData().getIdentityCard());
            queryVO.setIdentityCardFront(result.getData().getIdentityCardFront());
            queryVO.setIdentityCardBack(result.getData().getIdentityCardBack());
            queryVO.setLegalPersonName(result.getData().getLegalPersonName());
            queryVO.setLegalPersonPhone(result.getData().getLegalPersonPhone());
            queryVO.setLegalPersonIdentityCard(result.getData().getLegalPersonIdentityCard());
            queryVO.setLegalPersonIdentityCardFront(result.getData().getLegalPersonIdentityCardFront());
            queryVO.setLegalPersonIdentityCardBack(result.getData().getLegalPersonIdentityCardBack());
            queryVO.setUnifiedCreditCode(result.getData().getUnifiedCreditCode());
            queryVO.setRegisteredCapital(result.getData().getRegisteredCapital());
            queryVO.setEstablishmentDate(result.getData().getEstablishmentDate());
            queryVO.setBusinessLicence(result.getData().getBusinessLicence());
            queryVO.setRegisterArea(result.getData().getRegisterArea());
            queryVO.setRegisterAddress(result.getData().getRegisterAddress());
            queryVO.setProvinceName(result.getData().getProvinceName());
            queryVO.setCityName(result.getData().getCityName());
            queryVO.setLogo(result.getData().getLogo());
        }

        return Wrapper.success(queryVO);
    }

    /**
     * 根据会员Id列表，查询具有“服务提供者”角色类型的会员信息
     *
     * @param queryVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<List<MemberFeignBatchByIdQueryVO>> batchFindMembersByIdList(MemberFeignBatchByIdVO queryVO) {
        //todo 这个接口有问题
        //先查找所有下级会员
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("memberId").as(Long.class), queryVO.getMemberId()));
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.OTHER.getCode()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), MemberStatusEnum.NORMAL.getCode()));
            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        RoleTypeDO roleTypeDO = roleTypeRepository.findFirstByTypeEnum(RoleTypeEnum.SERVICE_PROVIDER.getCode());
        if (roleTypeDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_ROLE_TYPE_DOES_NOT_EXIST);
        }

        List<Long> subMemberIdList = relationRepository.findAll(specification).stream().map(MemberRelationDO::getSubMemberId).distinct().collect(Collectors.toList());

        List<RoleDO> roleDOList = roleRepository.findByRoleType(roleTypeDO);
        List<Long> roleIds = roleDOList.stream().map(RoleDO::getId).collect(Collectors.toList());

        specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));
            list.add(criteriaBuilder.equal(root.get("verified").as(Integer.class), MemberValidateStatusEnum.VERIFY_PASSED.getCode()));
            list.add(criteriaBuilder.equal(root.get("status").as(Integer.class), MemberStatusEnum.NORMAL.getCode()));

            Expression<Long> subMemberIdInExp = root.get("subMemberId").as(Long.class);
            list.add(subMemberIdInExp.in(subMemberIdList));

            Expression<Long> subRoleIdInExp = root.get("subRoleId").as(Long.class);
            list.add(subMemberIdInExp.in(roleIds));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        List<MemberRelationDO> memberRelationDOList = relationRepository.findAll(specification);
        List<MemberFeignBatchByIdQueryVO> queryVOList = memberRelationDOList.stream().map(relationDO -> {
            MemberFeignBatchByIdQueryVO feignQueryVO = new MemberFeignBatchByIdQueryVO();
            feignQueryVO.setMemberId(relationDO.getSubMemberId());
            feignQueryVO.setMemberName(relationDO.getSubMember().getName());
            feignQueryVO.setRoleId(relationDO.getSubRoleId());
            feignQueryVO.setRoleName(relationDO.getSubRoleName());
            feignQueryVO.setMemberTypeName(MemberTypeEnum.getMessage(relationDO.getSubMemberTypeEnum()));
            feignQueryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            feignQueryVO.setIsSubMember(subMemberIdList.contains(relationDO.getSubMemberId()) ? 1 : 0);
            return feignQueryVO;
        }).collect(Collectors.toList());

        return Wrapper.success(queryVOList);
    }

    /**
     * 根据会员Id列表，查询具有“服务提供者”角色类型的“平台会员”信息
     *
     * @param idsVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignShopQueryVO>> batchFindServiceProviderMemberByIdList(MemberFeignIdsVO idsVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));

            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));

            Expression<Long> subMemberIdInExp = root.get("subMemberId").as(Long.class);
            list.add(subMemberIdInExp.in(idsVO.getMemberIds()));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        List<MemberRelationDO> relationDOList = relationRepository.findAll(specification, Sort.by("id").ascending());

        return Wrapper.success(relationDOList.stream().map(relationDO -> {
            MemberFeignShopQueryVO queryVO = new MemberFeignShopQueryVO();
            queryVO.setMemberId(relationDO.getSubMemberId());
            queryVO.setName(relationDO.getSubMember().getName());
            queryVO.setRoleId(relationDO.getSubRoleId());
            queryVO.setRoleName(relationDO.getSubRoleName());
            queryVO.setLevel(relationDO.getLevelRight().getLevel());
            queryVO.setLevelTag(relationDO.getLevelRight().getLevelTag());
            queryVO.setStatus(relationDO.getStatus());
            queryVO.setRoleStatus(relationDO.getSubRole().getStatus());
            queryVO.setOuterStatus(relationDO.getOuterStatus());
            queryVO.setOuterStatusName(MemberOuterStatusEnum.getCodeMsg(relationDO.getOuterStatus()));
            queryVO.setRegisterYears(Period.between(relationDO.getCreateTime().toLocalDate(), LocalDateTime.now().toLocalDate()).getYears() + 1);
            queryVO.setCreditPoint(relationDO.getCredit().getCreditPoint());
            queryVO.setAvgTradeCommentStar(relationDO.getCredit().getAvgTradeCommentStar());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员名称，查询具有“服务提供者”角色类型的企业会员、企业个人会员的Id列表
     *
     * @param nameVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberFeignIdsResultVO> findMerchantAndProviderMemberIdListByName(MemberFeignNameVO nameVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));
            Join<Object, Object> subRoleJoin = root.join("subRole", JoinType.LEFT);
            list.add(criteriaBuilder.equal(subRoleJoin.get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));
            list.add(criteriaBuilder.or(criteriaBuilder.equal(subRoleJoin.get("memberType").get("typeEnum").as(Integer.class), MemberTypeEnum.MERCHANT.getCode()), criteriaBuilder.equal(subRoleJoin.get("memberType").get("typeEnum").as(Integer.class), MemberTypeEnum.MERCHANT_PERSONAL.getCode())));

            Join<Object, Object> subMemberJoin = root.join("subMember", JoinType.LEFT);
            list.add(criteriaBuilder.like(subMemberJoin.get("name").as(String.class), "%" + nameVO.getName().trim() + "%"));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        List<MemberRelationDO> relationDOList = relationRepository.findAll(specification, Sort.by("id").ascending());

        MemberFeignIdsResultVO resultVO = new MemberFeignIdsResultVO();
        resultVO.setMemberIds(relationDOList.stream().map(MemberRelationDO::getSubMemberId).distinct().collect(Collectors.toList()));

        return Wrapper.success(resultVO);
    }

    /**
     * 根据会员Id、角色Id查询平台会员信息
     * <p>其中等级为当前会员的平台等级</p>
     *
     * @param memberFeignVOList 接口参数
     * @return 查询结果
     **/
    @Override
    public Wrapper<List<MemberFeignQueryVO>> listPlatformMembers(List<MemberFeignVO> memberFeignVOList) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));

            //Or查询
            if (!CollectionUtils.isEmpty(memberFeignVOList)) {
                List<Predicate> orList = new ArrayList<>();
                for (MemberFeignVO item : memberFeignVOList) {
                    orList.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), item.getMemberId()), criteriaBuilder.equal(root.get("subRoleId").as(Long.class), item.getRoleId())));
                }
                Predicate[] orP = new Predicate[orList.size()];
                list.add(criteriaBuilder.or(orList.toArray(orP)));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification).stream().map(relationDO -> {
            MemberFeignQueryVO queryVO = new MemberFeignQueryVO();
            queryVO.setSubMemberName("");
            queryVO.setMemberId(relationDO.getSubMemberId());
            queryVO.setMemberName(relationDO.getSubMember().getName());
            queryVO.setLogo(StringUtils.hasLength(relationDO.getSubMember().getLogo()) ? relationDO.getSubMember().getLogo() : "");
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relationDO.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setRoleId(relationDO.getSubRoleId());
            queryVO.setRoleName(relationDO.getSubRole().getRoleName());
            queryVO.setLevelTag(relationDO.getLevelRight() == null ? "" : relationDO.getLevelRight().getLevelTag());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员Id和加密后的支付密码，校验支付密码
     *
     * @param checkVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<MemberFeignPayPswCheckResultVO> checkMemberPayPassword(MemberFeignPayPswCheckVO checkVO) {
        MemberDO memberDO = memberRepository.findById(checkVO.getMemberId()).orElse(null);
        if (memberDO == null) {
            return Wrapper.fail(ResponseCode.MC_MS_MEMBER_DOES_NOT_EXIST);
        }

        MemberFeignPayPswCheckResultVO resultVO = new MemberFeignPayPswCheckResultVO();
        if (StringUtils.hasLength(memberDO.getPayPassword())) {
            if (PasswordUtil.instance().checkPassword(memberDO.getPayPassword(), checkVO.getPayPassword())) {
                resultVO.setCheckResult(MemberPayPasswordCheckEnum.CORRECT.getCode());
            } else {
                resultVO.setCheckResult(MemberPayPasswordCheckEnum.INCORRECT.getCode());
            }
        } else {
            resultVO.setCheckResult(MemberPayPasswordCheckEnum.NOT_SET.getCode());
        }

        return Wrapper.success(resultVO);
    }

    /**
     * 批量查询会员Logo
     *
     * @param memberIds 会员id列表
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignLogoVO>> getMemberLogos(List<Long> memberIds) {
        if (CollectionUtils.isEmpty(memberIds)) {
            return Wrapper.success(new ArrayList<>());
        }

        List<MemberDO> memberDOList = memberRepository.findAllById(memberIds);

        return Wrapper.success(memberDOList.stream().map(memberDO -> {
            MemberFeignLogoVO logoVO = new MemberFeignLogoVO();
            logoVO.setMemberId(memberDO.getId());
            logoVO.setLogo(StringUtils.hasLength(memberDO.getLogo()) ? memberDO.getLogo() : "");
            return logoVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 批量查询会员角色名称
     *
     * @param roleIds 会员角色Id列表
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignRoleVO>> getRoles(List<Long> roleIds) {
        return Wrapper.success(roleRepository.findAllById(roleIds).stream().map(roleDO -> {
            MemberFeignRoleVO roleVO = new MemberFeignRoleVO();
            roleVO.setRoleId(roleDO.getId());
            roleVO.setRoleName(roleDO.getRoleName());
            return roleVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 根据会员ID批量查询IM客服用户
     * @param memberIds 会员id列表
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignImUserVO>> getImUsers(List<Long> memberIds) {
        if (CollectionUtil.isEmpty(memberIds)) {
            return Wrapper.fail("参数不能空");
        }

        List<MemberDO> memberDOList = memberRepository.findAllById(memberIds);
        List<MemberUserDO> memberUserDOList = memberUserRepository.findByMemberIn(memberDOList);
        List<MemberFeignImUserVO> memberFeignImUserVOList = memberUserDOList.stream().filter(a ->
                a.getRoles().stream().anyMatch(b -> b.getHasImAuth() != null && b.getHasImAuth().equals(1))).map(a -> {
            MemberFeignImUserVO memberFeignImUserVO = new MemberFeignImUserVO();
            memberFeignImUserVO.setMemberId(a.getMember().getId());
            memberFeignImUserVO.setMemberName(a.getMember().getName());
            memberFeignImUserVO.setMemberLogo(a.getMember().getLogo());
            memberFeignImUserVO.setUserId(a.getId());
            memberFeignImUserVO.setUserLogo(a.getLogo());
            memberFeignImUserVO.setUserName(a.getName());
            memberFeignImUserVO.setUserRoleName(a.getRoles().stream().findFirst().orElse(new MemberRoleDO()).getRoleName());
            return memberFeignImUserVO;
        }).collect(Collectors.toList());

        return Wrapper.success(memberFeignImUserVOList);
    }

    /**
     * 根据用户ID批量查询用户信息
     * @param userIds 用户id列表
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignUserVO>> getUsers(List<Long> userIds) {
        if (CollectionUtil.isEmpty(userIds)) {
            return Wrapper.fail("参数不能空");
        }

        List<MemberUserDO> memberUserDOList = memberUserRepository.findAllById(userIds);
        if (CollectionUtil.isEmpty(memberUserDOList)) {
            return Wrapper.fail("数据记录不存在");
        }

        List<MemberFeignUserVO> memberFeignUserVOList = memberUserDOList.stream().map(a -> {
            MemberFeignUserVO memberFeignUserVO = new MemberFeignUserVO();
            memberFeignUserVO.setMemberId(a.getMember().getId());
            memberFeignUserVO.setMemberName(a.getMember().getName());
            memberFeignUserVO.setMemberLogo(a.getMember().getLogo());
            memberFeignUserVO.setUserId(a.getId());
            memberFeignUserVO.setUserLogo(a.getLogo());
            memberFeignUserVO.setUserName(a.getName());
            return memberFeignUserVO;
        }).collect(Collectors.toList());

        return Wrapper.success(memberFeignUserVOList);
    }

    /**
     * 订单服务，查询流程规则适用会员列表
     *
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberFeignPageQueryVO>> findPlatformMembers(List<MemberFeignVO> feignVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));

            //动态拼接多个Or查询
            List<Predicate> orList = new ArrayList<>();
            for (MemberFeignVO member : feignVO) {
                orList.add(criteriaBuilder.and(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), member.getMemberId()), criteriaBuilder.equal(root.get("subRoleId").as(Long.class), member.getRoleId())));
            }
            Predicate[] orP = new Predicate[orList.size()];
            list.add(criteriaBuilder.or(orList.toArray(orP)));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };
        return Wrapper.success(relationRepository.findAll(specification).stream().map(relation -> {
            MemberFeignPageQueryVO queryVO = new MemberFeignPageQueryVO();
            queryVO.setMemberId(relation.getSubMemberId());
            queryVO.setRoleId(relation.getSubRoleId());
            queryVO.setName(relation.getSubMember().getName());
            queryVO.setRoleName(relation.getSubRole().getRoleName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relation.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setLevel(relation.getLevelRight() == null ? 0 : relation.getLevelRight().getLevel());
            queryVO.setLevelTag(relation.getLevelRight() == null ? "" : relation.getLevelRight().getLevelTag());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 订单服务，商户支付参数配置，查询平台服务提供者企业会员列表
     *
     * @param paymentVO 接口参数
     * @return 查询结果
     **/
    @Override
    public Wrapper<List<MemberFeignPageQueryVO>> findProviderMerchant(MemberFeignPaymentVO paymentVO) {
        Specification<MemberRelationDO> specification = (Specification<MemberRelationDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();
            list.add(criteriaBuilder.equal(root.get("relType").as(Integer.class), MemberRelationTypeEnum.PLATFORM.getCode()));

            list.add(criteriaBuilder.equal(root.get("subRole").get("roleType").get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));
            list.add(criteriaBuilder.or(criteriaBuilder.equal(root.get("subRole").get("memberType").get("typeEnum").as(Integer.class), MemberTypeEnum.MERCHANT.getCode()), criteriaBuilder.equal(root.get("subRole").get("memberType").get("typeEnum").as(Integer.class), MemberTypeEnum.MERCHANT_PERSONAL.getCode())));

            if (StringUtils.hasText(paymentVO.getName())) {
                list.add(criteriaBuilder.like(root.get("subMember").get("name").as(String.class), "%" + paymentVO.getName().trim() + "%"));
            }

            //动态拼接多个Or查询
            if(!CollectionUtils.isEmpty(paymentVO.getMembers())) {
                List<Predicate> orList = paymentVO.getMembers().stream().map(member -> criteriaBuilder.and(criteriaBuilder.equal(root.get("subMemberId").as(Long.class), member.getMemberId()), criteriaBuilder.equal(root.get("subRoleId").as(Long.class), member.getRoleId()))).collect(Collectors.toList());
                Predicate[] orP = new Predicate[orList.size()];
                list.add(criteriaBuilder.or(orList.toArray(orP)));
            }

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        return Wrapper.success(relationRepository.findAll(specification).stream().map(relation -> {
            MemberFeignPageQueryVO queryVO = new MemberFeignPageQueryVO();
            queryVO.setMemberId(relation.getSubMemberId());
            queryVO.setRoleId(relation.getSubRoleId());
            queryVO.setName(relation.getSubMember().getName());
            queryVO.setRoleName(relation.getSubRole().getRoleName());
            queryVO.setMemberTypeName(MemberTypeEnum.getCodeMessage(relation.getSubRole().getMemberType().getTypeEnum()));
            queryVO.setLevel(relation.getLevelRight() == null ? 0 : relation.getLevelRight().getLevel());
            queryVO.setLevelTag(relation.getLevelRight() == null ? "" : relation.getLevelRight().getLevelTag());
            return queryVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 查询是否下级会员
     *
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<Boolean> isSubMember(MemberRelationFeignVO feignVO) {
        MemberRelationDO relationDO = relationRepository.findFirstByMemberIdAndRoleIdAndSubMemberIdAndSubRoleId(feignVO.getUpperMemberId(), feignVO.getUpperRoleId(), feignVO.getMemberId(), feignVO.getRoleId());
        if (relationDO == null || relationDO.getVerified().equals(MemberValidateStatusEnum.VERIFY_NOT_PASSED.getCode()) || relationDO.getStatus().equals(MemberStatusEnum.ELIMINATED.getCode()) || relationDO.getStatus().equals(MemberStatusEnum.BLACK_LIST.getCode())) {
            return Wrapper.success(false);
        } else {
            return Wrapper.success(true);
        }
    }

    @Override
    public Wrapper<List<AtSubMemberSuitableMemberVO>> listAbilitySubMemberSuitableMember(MemberAndUpperMembersVO memberAndUpperMembersVO) {
        // 查找与上级会员的关系
        List<MemberRelationDO> relationDOList = relationRepository.findBySubMemberIdAndSubRoleIdAndVerified(memberAndUpperMembersVO.getSubMemberId(), memberAndUpperMembersVO.getSubRoleId(), MemberValidateStatusEnum.VERIFY_PASSED.getCode());
        if (CollectionUtils.isEmpty(relationDOList)) {
            Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }
        List<AtSubMemberSuitableMemberVO> resultList = new ArrayList<>();
        for (MemberFeignVO upperMemberRole : memberAndUpperMembersVO.getUpperMemberRoles()) {
            AtSubMemberSuitableMemberVO atSubMemberSuitableMemberVO = new AtSubMemberSuitableMemberVO();

            MemberRelationDO relationDO = relationDOList.stream().filter(e -> e.getMemberId().equals(upperMemberRole.getMemberId()) && e.getRoleId().equals(upperMemberRole.getRoleId())).findFirst().orElse(null);
            if (Objects.isNull(relationDO)) {
                // 没有找到关系,继续寻找与平台的关系
                MemberRelationDO platformRelationDO = relationDOList.stream().filter(e -> MemberLevelTypeEnum.PLATFORM.getCode().equals(e.getSubMemberLevelTypeEnum())).findFirst().orElse(null);
                if (Objects.nonNull(platformRelationDO)) {
                    LocalDateTime depositTime = platformRelationDO.getDepositTime();
                    if (Objects.nonNull(depositTime)) {
                        // 入库时间在当前时间前
                        if (depositTime.isBefore(DateTimeUtil.getToday())) {
                            atSubMemberSuitableMemberVO.setOldUser(true);
                        } else {
                            atSubMemberSuitableMemberVO.setNewUser(true);
                        }
                    }
                }
            } else {
                // 找到关系, 判断是否为商户会员或渠道会员
                if (MemberLevelTypeEnum.MERCHANT.getCode().equals(relationDO.getSubMemberLevelTypeEnum())
                        || MemberLevelTypeEnum.CHANNEL.getCode().equals(relationDO.getSubMemberLevelTypeEnum())) {
                    // 上级为商户会员或上级为渠道会员
                    atSubMemberSuitableMemberVO.setSubMemberRelation(true);
                    LocalDateTime depositTime = relationDO.getDepositTime();
                    if (Objects.nonNull(depositTime)) {
                        // 入库时间在当前时间前
                        if (depositTime.isBefore(DateTimeUtil.getToday())) {
                            atSubMemberSuitableMemberVO.setOldMember(true);
                        } else {
                            atSubMemberSuitableMemberVO.setNewMember(true);
                        }
                    }

                    atSubMemberSuitableMemberVO.setMemberType(relationDO.getSubMemberTypeEnum());
                    atSubMemberSuitableMemberVO.setRoleType(relationDO.getSubRole().getRoleType().getTypeEnum());
                    atSubMemberSuitableMemberVO.setLevelType(relationDO.getSubMemberLevelTypeEnum());
                    atSubMemberSuitableMemberVO.setLevel(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getLevel());
                }
            }

            atSubMemberSuitableMemberVO.setUpperMemberId(upperMemberRole.getMemberId());
            atSubMemberSuitableMemberVO.setUpperRoleId(upperMemberRole.getRoleId());
            atSubMemberSuitableMemberVO.setMemberId(memberAndUpperMembersVO.getSubMemberId());
            atSubMemberSuitableMemberVO.setRoleId(memberAndUpperMembersVO.getSubRoleId());

            resultList.add(atSubMemberSuitableMemberVO);
        }
        return Wrapper.success(resultList);
    }

    @Override
    public Wrapper<PfSubMemberSuitableMemberVO> getPlatformSubMemberSuitableMember(MemberFeignVO memberFeignVO) {
        // 查询所有下级会员的平台关系
        MemberRelationDO relationDO = relationRepository.findFirstBySubMemberIdAndSubRoleIdAndRelTypeAndVerified(memberFeignVO.getMemberId(), memberFeignVO.getRoleId(), MemberRelationTypeEnum.PLATFORM.getCode(), MemberValidateStatusEnum.VERIFY_PASSED.getCode());
        if (Objects.isNull(relationDO)) {
            Wrapper.fail(ResponseCode.MC_MS_MEMBER_RELATION_DOES_NOT_EXIST);
        }

        PfSubMemberSuitableMemberVO pfSubMemberSuitableMemberVO = new PfSubMemberSuitableMemberVO();

        LocalDateTime depositTime = relationDO.getDepositTime();
        if (Objects.nonNull(depositTime)) {
            // 入库时间在当前时间前
            if (depositTime.isBefore(DateTimeUtil.getToday())) {
                pfSubMemberSuitableMemberVO.setOldMember(true);
            } else {
                pfSubMemberSuitableMemberVO.setNewMember(true);
            }
        }

        pfSubMemberSuitableMemberVO.setMemberId(relationDO.getSubMemberId());
        pfSubMemberSuitableMemberVO.setRoleId(relationDO.getSubRoleId());
        pfSubMemberSuitableMemberVO.setMemberType(relationDO.getSubMemberTypeEnum());
        pfSubMemberSuitableMemberVO.setRoleType(relationDO.getSubRole().getRoleType().getTypeEnum());
        pfSubMemberSuitableMemberVO.setLevel(relationDO.getLevelRight() == null ? 0 : relationDO.getLevelRight().getLevel());
        pfSubMemberSuitableMemberVO.setLevelType(relationDO.getSubMemberLevelTypeEnum());

        return Wrapper.success(pfSubMemberSuitableMemberVO);
    }

    /**
     * 模板服务 - 新增或更新店铺Logo
     *
     * @param feignVO 接口参数
     * @return 操作结果
     */
    @Override
    public Wrapper<Void> insertOrUpdateMemberShop(MemberShopFeignVO feignVO) {
        return baseMemberShopService.insertOrUpdateMemberShop(feignVO.getMemberId(), feignVO.getRoleId(), feignVO.getName(), feignVO.getLogo());
    }

    /**
     * 所有服务通用 - 查询平台规则配置
     *
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberRuleDetailVO>> findMemberRules(MemberRuleDetailFeignVO feignVO) {
        QBaseMemberRuleDO qBaseMemberRule = QBaseMemberRuleDO.baseMemberRuleDO;
        JPAQuery<MemberRuleDetailVO> query = jpaQueryFactory.select(Projections.constructor(MemberRuleDetailVO.class, qBaseMemberRule.ruleType, qBaseMemberRule.ruleName, qBaseMemberRule.methodCode, qBaseMemberRule.methodName, qBaseMemberRule.status))
                .from(qBaseMemberRule);

        if(NumberUtil.notNullOrZero(feignVO.getRuleType())) {
            query.where(qBaseMemberRule.ruleType.eq(feignVO.getRuleType()));
        }

        if(NumberUtil.notNullOrZero(feignVO.getMethodCode())) {
            query.where(qBaseMemberRule.methodCode.eq(feignVO.getMethodCode()));
        }

        if(NumberUtil.notNullOrZero(feignVO.getStatus())) {
            query.where(qBaseMemberRule.status.eq(feignVO.getStatus()));
        }

        return Wrapper.success(query.fetch());
    }

    /**
     * 根据会员关系，查询业务员Id
     *
     * @param feignVO 接口参数
     * @return 查询结果
     */
    @Override
    public Wrapper<List<MemberSalesFeignVO>> findMemberSales(List<MemberFeignRelationVO> feignVO) {
        QMemberUserChannelDO qMemberUserChannel = QMemberUserChannelDO.memberUserChannelDO;

        //Step 1: 拼接查询条件
        com.querydsl.core.types.Predicate[] predicates = feignVO.stream().map(feign -> qMemberUserChannel.memberId.eq(feign.getUpperMemberId()).and(qMemberUserChannel.roleId.eq(feign.getUpperRoleId())).and(qMemberUserChannel.subMemberId.eq(feign.getSubMemberId())).and(qMemberUserChannel.subRoleId.eq(feign.getSubRoleId()))).toArray(com.querydsl.core.types.Predicate[]::new);
        List<MemberUserChannelDO> channels = jpaQueryFactory.select(qMemberUserChannel).from(qMemberUserChannel).where(ExpressionUtils.anyOf(predicates)).fetch();

        return Wrapper.success(feignVO.stream().map(feign -> {
            MemberSalesFeignVO salesFeignVO = new MemberSalesFeignVO();
            salesFeignVO.setMemberId(feign.getUpperMemberId());
            salesFeignVO.setRoleId(feign.getUpperRoleId());
            salesFeignVO.setSubMemberId(feign.getSubMemberId());
            salesFeignVO.setSubRoleId(feign.getSubRoleId());
            salesFeignVO.setUserId(channels.stream().filter(channel -> channel.getMemberId().equals(feign.getUpperMemberId()) && channel.getRoleId().equals(feign.getUpperRoleId()) && channel.getSubMemberId().equals(feign.getSubMemberId()) && channel.getSubRoleId().equals(feign.getSubRoleId())).map(MemberUserChannelDO::getUserId).findFirst().orElse(0L));
            return salesFeignVO;
        }).collect(Collectors.toList()));
    }

    /**
     * 筛选角色类型为服务提供者的会员
     * @param members 会员Id和角色Id的缓存实体
     * @return 筛选结果
     */
    @Override
    public Wrapper<List<MemberAndRoleIdDTO>> screenMemberUser(List<MemberAndRoleIdDTO> members) {
        Specification<RoleDO> specification = (Specification<RoleDO>) (root, query, criteriaBuilder) -> {
            List<Predicate> list = new ArrayList<>();

            list.add(criteriaBuilder.in(root.get("id")).value(members.stream().map(MemberAndRoleIdDTO::getRoleId).collect(Collectors.toList())));
            Join<RoleDO, RoleTypeDO> roleTypeJoin = root.join("roleType", JoinType.LEFT);
            list.add(criteriaBuilder.equal(roleTypeJoin.get("typeEnum").as(Integer.class), RoleTypeEnum.SERVICE_PROVIDER.getCode()));

            Predicate[] p = new Predicate[list.size()];
            return criteriaBuilder.and(list.toArray(p));
        };

        List<RoleDO> roleDOS = roleRepository.findAll(specification);
        List<Long> ids = roleDOS.stream().map(RoleDO::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(roleDOS)){
            return Wrapper.success(new ArrayList<>());
        }
        return Wrapper.success(members.stream().filter(merberAndRoleId -> ids.contains(merberAndRoleId.getRoleId())).collect(Collectors.toList()));
    }
}
